home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
Scott's Soul
/
Beep.c
next >
Wrap
C/C++ Source or Header
|
1996-06-21
|
3KB
|
138 lines
// Note: This will not work with Copland. Don't even think of it.
#include <Events.h>
#include <Resources.h>
#include <Memory.h>
#include <ToolUtils.h>
#include <Traps.h>
#include <Balloons.h>
#include <Sound.h>
#include <A4Stuff.h>
#define kOptionKey 0x3A
PicHandle gDogCow;
PicHandle gScottSuckup;
Boolean isPressed(unsigned short k );
extern pascal void ShowIcon7(short iconId, Boolean advance);
pascal void (*gOldSysBeep)(short notUsedAnyMore);
pascal void HelpSysBeep(short notUsedAnyMore);
// This procedure is called one time at system startup. I install my
// patch to the SysBeep call. After this, whenever the system calls
// SysBeep, my code in "HelpSysBeep" will be executed instead.
void main(void)
{
long oldA4;
THz oldZone;
// Set up A4, so we can access our globals.
oldA4 = SetCurrentA4();
ShowIcon7(128, true);
// Set the current zone to the system zone. In the 680x0 case, this
// is not necessary, but it's not a bad idea and it keeps us out of
// trouble when traps that we don't expect to have side effects
// unexpectedlty allocate memory from the current zone. One example
// of this is the NewRoutineDescriptor routine.
oldZone = GetZone();
SetZone(SystemZone());
// We need to detach our code, so that we stay around.
DetachResource(GetResource('INIT', -4048));
// Get our dogcow beep picture
gDogCow = (PicHandle)GetResource('PICT', 1000);
DetachResource((Handle)gDogCow);
// Get our ScottSuckup beep picture
gScottSuckup = (PicHandle)GetResource('PICT', 1);
DetachResource((Handle)gScottSuckup);
#ifdef DOESNOTWORK
// Get our dogcow beep sound
gDogCowSound = (SndListHandle)GetResource('snd ', 1000);
DetachResource((Handle)gDogCowSound);
#endif
// Remember the old implementation of SysBeep.
gOldSysBeep = (void *) GetToolTrapAddress(_SysBeep);
// Patch ourselves in.
SetToolTrapAddress( (ProcPtr) HelpSysBeep, _SysBeep);
// Restore the old zone again
SetZone(oldZone);
// And restore the value of A4 on the way out.
SetA4(oldA4);
}
// This is my replacement to SysBeep. After we have set the SysBeep
// trap to point here (up in "main") then whenever anyone calls the
// SysBeep trap, we execute here instead.
pascal void HelpSysBeep(short notUsedAnyMore)
{
#pragma unused (notUsedAnyMore)
long oldA4;
Boolean helpIsOn;
HMMessageRecord aHelpMsg;
Point tip;
// Set up A4, so we can access our globals.
oldA4 = SetCurrentA4();
helpIsOn = HMGetBalloons();
// turn on help if it isn't on
if (helpIsOn == false)
HMSetBalloons(true);
// display a 'PICT' instead of beeping
aHelpMsg.hmmHelpType = khmmPictHandle;
if (isPressed(kOptionKey))
aHelpMsg.u.hmmPictHandle = gDogCow;
else
aHelpMsg.u.hmmPictHandle = gScottSuckup;
// if you wanted a pure text string instead, use this:
//aHelpMsg.hmmHelpType = khmmString;
//BlockMove ("\pBeep!", aHelpMsg.u.hmmString, 6);
GetMouse(&tip);
LocalToGlobal(&tip);
// Show the balloon
HMShowBalloon(&aHelpMsg,tip,nil,nil,0,0,kHMSaveBitsNoWindow);
// Call the old SysBeep:
gOldSysBeep(notUsedAnyMore);
while (Button())
;
// turn off help if it wasn't on coming into this patch
if (helpIsOn == false)
HMSetBalloons(false);
// And restore the value of A4 on the way out.
SetA4(oldA4);
return;
}
Boolean isPressed(unsigned short k )
// k = any keyboard scan code, 0-127
{
unsigned char km[16];
GetKeys( (unsigned long *) km);
return ( ( km[k>>3] >> (k & 7) ) & 1);
}